﻿package ahxu.crawler;

import java.io.File;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

public class DefaultCrawlerResultDao implements ICrawlerResutlDao {

	private static final Log logger = LogFactory.getLog(DefaultCrawlerResultDao.class);

	private DataSource dataSource;
	public static final String table="CRAWL_RESULT";
	private String saveRootPath;
	public DefaultCrawlerResultDao(DataSource dataSource,String saveRootPath){
		this.dataSource=dataSource;
		this.saveRootPath=saveRootPath;
	}
	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public DefaultCrawlerResultDao(DataSource dataSource){
		this.dataSource=dataSource;
	}
	
	private File getSaveFilePath(){
		
		Calendar rightNow = Calendar.getInstance();
		int year=rightNow.get(Calendar.YEAR);
		int month=rightNow.get(Calendar.MONTH);
		int day=rightNow.get(Calendar.DAY_OF_MONTH);
		String filename=String.valueOf(System.currentTimeMillis())+".html";
		String path=FilenameUtils.concat(this.getSaveRootPath(), String.valueOf(year));
		path=FilenameUtils.concat(path, String.valueOf(month+1));
		path=FilenameUtils.concat(path, String.valueOf(day));
		path=FilenameUtils.concat(path, String.valueOf(filename));
		return new File(path);
	}
	
	private boolean isExist(String md5){
		String sql="select count(*) from "+table+" where md5=?";
		SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
		int result=simpleJdbcTemplate.queryForInt(sql, md5);
		if(result==1) return true;
		else return false;
	}
	
	public String saveCrawlerResult(CrawlerResult object) throws CrawlerResultDaoException {
		try{
			if(isExist(object.getSourceMd5())) {
				logger.warn("the content of url["+object.getUri().toString()+"] has already existed!");
				return null;
			}
			File saveFile=getSaveFilePath();
			FileUtils.writeByteArrayToFile(saveFile, object.getSource());
			String filename=saveFile.getAbsolutePath();
			logger.info("save content to file["+filename+"]");
			if(this.dataSource!=null){
				String insertSQL="insert into " +table+
				"(ID,ANCHOR_TEXT,URL,SOURCE_FILE,MD5, DONE)" +
				"values" +
				"(?,?,?,?,?,?)";
				SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);

				simpleJdbcTemplate.update(insertSQL,
						object.getId(),
						object.getAnthorText(),
						object.getUri(),
						filename,
						object.getSourceMd5(),
						false);
			}
			logger.info("save content to db");
			return object.getId();
		}catch(Exception e){
			logger.error(e.getMessage());
			throw new CrawlerResultDaoException(e);
		}
	}

	public String getSaveRootPath() {
		return saveRootPath;
	}

	public void setSaveRootPath(String saveRootPath) {
		this.saveRootPath = saveRootPath;
	}
	public List<CrawlerSaveResult> findUndoneResultsByTop(int top) throws CrawlerResultDaoException {
		try{
			List<CrawlerSaveResult> ret = new ArrayList<CrawlerSaveResult>();
			String sql = "select TOP ? * from " + table + " where done=?";

			SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(
					dataSource);

			ParameterizedRowMapper<CrawlerSaveResult> mapper = new ParameterizedRowMapper<CrawlerSaveResult>() {

				// notice the return type with respect to Java 5 covariant
				// return types
				public CrawlerSaveResult mapRow(ResultSet rs, int rowNum)
						throws SQLException {
					CrawlerSaveResult obj = new CrawlerSaveResult();
					obj.setId(rs.getString("id"));
					obj.setAnchorText(rs.getString("ANCHOR_TEXT"));
					obj.setUrl(rs.getString("url"));
					obj.setDone(rs.getBoolean("done"));
					obj.setSourceFile(rs.getString("SOURCE_FILE"));
					return obj;
				}
			};
			ret = simpleJdbcTemplate.query(sql, mapper, top, false);

			return ret;
		}catch(Exception e){
			throw new CrawlerResultDaoException(e);
		}
	}
	public int updateResultDone(String id,boolean value) throws CrawlerResultDaoException {
		String sql="update " +table+ " set done=? where id=?";
		SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
		return simpleJdbcTemplate.update(sql, value,id);
		
	}

}
